<template>
  <div class="widget-states-dock">
    <el-form :model="widget" label-width="30px" size="mini">
      <div class="pad-divider">
        <div class="flex-com mar-btm">
          <span class="label-title">名称</span>
          <el-input
            class="state-input" v-model="widget.name" placeholder="请填写组件名称"
            @change="(val) => widgetBasicBulkChange('name', val)" size="mini"></el-input>
        </div>
        <div class="flex-com mar-btm">
          <span class="label-title">组件ID</span>
          <el-input class="state-input" v-model="widget.editId" :disabled="isEditId" size="mini" clearable
                    @change="(val) => widgetBasicBulkChange('editId', val)" @blur="isEditId=true"></el-input>
          <el-tooltip effect="dark" content="编辑" placement="top">
            <i class="el-icon-edit cursor-pointer font-weight-bold font-hover-primary mar-lft-10"
               @click="isEditId=false"></i>
          </el-tooltip>
          <el-tooltip effect="dark" content="复制" placement="top">
            <i
              class="el-icon-copy-document cursor-pointer font-weight-bold font-hover-primary mar-lft-10"
              @click="copyDomText(widget.editId)"></i>
          </el-tooltip>
        </div>
        <div class="flex-com mar-btm">
          <span class="label-title">组件源</span>
          <el-input class="state-input" v-model="sourceText" disabled size="mini"></el-input>
        </div>
        <div class="flex-com" v-if="!widget.relateSubPage">
          <span class="font-size-14 mar-rgt">分控修改</span>
          <el-radio-group
            v-model="widget.editableByControl"
            size="mini" class="state-input"
            @change="(val) => widgetBasicBulkChange('editableByControl', val)">
            <el-radio :label="true">支持</el-radio>
            <el-radio :label="false">不支持</el-radio>
          </el-radio-group>
        </div>

      </div>
      <div class="pad-divider pad-top-10">
        <RectControl :widget="srcWidget"></RectControl>
      </div>
      <div v-if="!widget.relateSubPage" class="pad-divider">
        <div class="flex-com">
          <span class="font-size-14 mar-rgt">默认显隐</span>
          <el-radio-group
            v-model="widget.visible"
            size="mini" class="state-input"
            @change="(val) => widgetBasicBulkChange('visible', val)">
            <el-radio :label="true">显示</el-radio>
            <el-radio :label="false">隐藏</el-radio>
          </el-radio-group>
        </div>
      </div>
      <!--子页面引用没有state-->
      <el-tabs
        v-if="editable" v-model="widget.UI.state"
        :addable="true" type="border-card"
        @tab-click="stateTabClick"
        @edit="stateTabEdit">
        <el-tab-pane
          v-for="(state, idx) in widget.UI.states" :key="state.id"
          :label="state.stateName" :name="state.id.toString()"
          :closable="idx !== 0">
          <el-form :model="state" label-width="65px" size="mini">
            <div class="pad-divider">
              <div class="flex-com">
                <span class="label-title">状态名</span>
                <el-input
                  v-model="state.stateName"
                  size="mini" placeholder="请填写状态名称"
                  class="state-input"
                  @change="(val) => stateBasicBulkChange('stateName', val)"></el-input>
              </div>
              <div
                v-if="widget.category === 'slider' || widget.category === 'level' "
                class="flex-com mar-top-20">
                <span class="label-title">值绑定</span>
                <el-input-number
                  v-model="state.values.value"
                  placeholder="请填写状态值"
                  controls-position="right" size="mini"
                  class="state-input width-100"
                  :min="widget.UI.data.minLimit"
                  :max="widget.UI.data.maxLimit"
                  @change="(val) => stateValuesBulkChange('values.value', val)"></el-input-number>
              </div>
              <div
                v-if="widget.category === 'processor'"
                class="flex-com mar-top-20">
                <span class="label-title">值绑定</span>
                <el-input-number
                  v-model="state.values.value"
                  :min="0"
                  :max="widget.UI.data.seconds"
                  placeholder="请填写状态值"
                  controls-position="right" size="mini"
                  class="state-input width-100"
                  @change="(val) => stateValuesBulkChange('values.value', val)"></el-input-number>
              </div>
              <div v-if="widget.category === 'switch'" class="flex-com mar-top-20">
                <span class="label-title">开关值</span>
                <el-select
                  v-model="state.values.switch"
                  size="mini" class="state-input width-100"
                  @change="(val) => stateValuesBulkChange('values.switch', val)">
                  <el-option label="开" :value=true></el-option>
                  <el-option label="关" :value=false></el-option>
                </el-select>
              </div>
              <div v-if="widget.category === 'inputNumber'" class="flex-com mar-top-20">
                <span class="label-title">数值</span>
                <el-input-number
                  v-model="state.values.number"
                  placeholder="请填写数值"
                  controls-position="right" size="mini"
                  class="state-input width-100"
                  @change="(val) => stateValuesBulkChange('values.number', val)">
                </el-input-number>
              </div>
              <div v-if="['urlPlayer', 'webView','qrCode'].includes(widget.category)" class="flex-com mar-top-20">
                <span class="label-title">链接</span>
                <el-input
                  v-model="state.values.url"
                  placeholder="请填写链接值" size="mini"
                  class="state-input width-100"
                  @change="(val) => stateValuesBulkChange('values.url', val)">
                </el-input>
              </div>
            </div>
            <!--字体-->
            <div
              v-if="['iconTextButton', 'text', 'input', 'dateTime','inputNumber'].includes(widget.category)"
              class="pad-divider position-relative">
              <div class="header6 mar-btm">文本</div>
              <el-tooltip
                v-if="['iconTextButton', 'text'].includes(widget.category)"
                content="应用文本值至其他状态" :open-delay="300" placement="top">
                <i
                  class="el-icon-connection font-color-primary font-size-16 font-weight-bold cursor-pointer"
                  style="position: absolute; top: 15px; right: 10px"
                  @click="textApplyToAllStates(state.values.text)"></i>
              </el-tooltip>
              <div class="flex-com mar-btm" v-if="state.values">
                <span class="label-title">文本值</span>
                <el-input
                  v-if="['iconTextButton', 'text'].includes(widget.category)"
                  v-model="state.values.text"
                  type="textarea" placeholder="请填写文本"
                  size="mini" class="state-input" :rows="2"
                  @input="(val) => stateValueTextInput(self, val)"></el-input>
                <el-input
                  v-else v-model="state.values.text"
                  placeholder="请填写文本"
                  size="mini" class="state-input"
                  @change="(val) => stateValuesBulkChange('values.text', val)"></el-input>
              </div>
              <el-row :gutter="10" class="mar-btm">
                <el-col :span="10">
                  <div class="comBox">
                    <PopoverColor :colorValue="state.textStyle.color">
                      <CustomColorPicker
                        v-model="state.textStyle.color" show-alpha
                        @change="(val) => stateStylesBulkChange('textStyle.color', val)"></CustomColorPicker>
                    </PopoverColor>
                  </div>
                </el-col>
                <el-col :span="14">
                  <el-input-number
                    v-model="state.textStyle.size"
                    placeholder="请填写字体大小"
                    controls-position="right"
                    class="width-100 width-input"
                    @change="(val) => stateStylesBulkChange('textStyle.size', val)" size="mini">
                  </el-input-number>
                </el-col>
                <el-col :span="10" class="mar-top-10">
                  <el-select v-model="state.textStyle.weight" size="mini" class="width-input"
                             @change="(val) => stateStylesBulkChange('textStyle.weight', val)">
                    <el-option label="常规" value="normal"></el-option>
                    <el-option label="加粗" value="bold"></el-option>
                  </el-select>
                </el-col>
                <el-col :span="14" class="mar-top-10">
                  <el-select v-model="state.textStyle.align" size="mini" class="width-input" placeholder="对齐方式"
                             @change="(val) => stateStylesBulkChange('textStyle.align', val)">
                    <el-option v-for="align in fontAlign" :key="align.value"
                               :label="align.label" :value="align.value">
                      <div class="flex-justify-start">
                        <i :class="align.icon" class="iconfont font-size-18"></i>
                        <span class="mar-lft-5">{{align.label}}</span>
                      </div>
                    </el-option>
                  </el-select>
                </el-col>
              </el-row>
            </div>
            <!--图标-->
            <div v-if="['iconTextButton', 'iconButton','indicator'].includes(widget.category)" class="pad-divider">
              <div class="header6 mar-btm">图标</div>
              <el-row :gutter="10">
                <el-col :span="6">
                  <div class="comBox">
                    <PopoverColor :colorValue="state.iconStyle.color">
                      <CustomColorPicker
                        v-model="state.iconStyle.color" show-alpha
                        @change="(val) => stateStylesBulkChange('iconStyle.color', val)"></CustomColorPicker>
                    </PopoverColor>
                  </div>
                </el-col>
                <el-col :span="9" v-if="widget.category!=='indicator'">
                  <div class="comBox flex-justify-between pad-lft-5">
                    <el-popover width="300" trigger="click" popper-class="custom-popover">
                      <div slot="reference" class="cursor-pointer">
                        <i v-if="state.values.icon" :class="backgroundIconClass" class="iconfont font-size-20"></i>
                        <div v-else style="width: 28px; height: 28px; border: 1px #CCCCCC dashed;"></div>
                      </div>
                      <div class="pad-all-5">
                        <IconPicker
                          v-model="state.values.icon"
                          @change="(val) => stateValuesBulkChange('values.icon', val)"></IconPicker>
                      </div>
                    </el-popover>
                    <div class="font-color-danger cursor-pointer" @click="stateValuesBulkChange('values.icon','')">
                      <i class="iconfont icon-del font-size-12"></i>
                      <span class="font-size-12">清空</span>
                    </div>
                  </div>
                </el-col>
                <el-col :span="9">
                  <el-input-number
                    v-model="state.iconStyle.size" :min="0" placeholder="请填写字体大小"
                    controls-position="right" size="mini" class="width-100"
                    @change="(val) => stateValuesBulkChange('iconStyle.size', val)"
                  ></el-input-number>
                </el-col>
              </el-row>
            </div>
            <!--背景-->
            <div
              v-if="!['processor', 'slider', 'level', 'selectInput'].includes(widget.category)"
              class="pad-divider">
              <div class="header6 mar-btm">填充</div>
              <el-row :gutter="10">
                <el-col :span="6">
                  <div class="comBox">
                    <PopoverColor :isBackgroundColor="true" :backgroundColorObject="backgroundColorObject">
                      <CustomColorPicker
                        ref="colorPicker" :isBackgroundColor="true" :backgroundColorObject="backgroundColorObject"
                        show-alpha
                        @change="(val) => stateStylesBulkChange('backStyle.backgroundColor', val)"
                        @confirmBgColor="confirmBgColor"
                      ></CustomColorPicker>
                    </PopoverColor>
                  </div>
                </el-col>
                <el-col :span="9">
                  <div class="comBox flex-justify-between pad-lft-5">
                    <el-popover width="350" trigger="click" popper-class="custom-popover"
                                @show="jumpToImage(state.backStyle.backgroundImage)">
                      <div slot="reference" class="cursor-pointer">
                        <el-image
                          v-if="backgroundImgSrc" :src="backgroundImgSrc"
                          class="display-block"
                          style="width: 25px; height: 25px;"></el-image>
                        <div v-else style="width: 28px; height: 28px; border: 1px #CCCCCC dashed;"></div>
                      </div>
                      <div class="pad-all-5">
                        <ImagePicker
                          v-model="state.backStyle.backgroundImage"
                          @change="(val) => stateStylesBulkChange('backStyle.backgroundImage', val)"></ImagePicker>
                      </div>
                    </el-popover>
                    <div class="font-color-danger cursor-pointer"
                         @click="stateStylesBulkChange('backStyle.backgroundImage','') ">
                      <i class="iconfont icon-del font-size-12"></i>
                      <span class="font-size-12">清空</span>
                    </div>
                  </div>
                </el-col>
              </el-row>
            </div>
            <!--边框-->
            <div class="pad-divider">
              <div class="header6 mar-btm">
                <span>边框</span>
                <el-button type="text" class="font-color-danger mar-lft-10" @click="clearAll('border')">
                  <i class="iconfont icon-del"></i><span>清空</span>
                </el-button>
              </div>
              <el-row :gutter="10">
                <el-col :span="12">
                  <el-input-number
                    v-model="state.backStyle.border.width"
                    size="mini" controls-position="right" :min="0" class="width-input"
                    @change="bdAllWidthChange"></el-input-number>
                </el-col>
                <el-col :span="6">
                  <div class="comBox">
                    <PopoverColor :colorValue="state.backStyle.border.color">
                      <CustomColorPicker
                        v-model="state.backStyle.border.color" show-alpha
                        @change="bdAllColorChange"></CustomColorPicker>
                    </PopoverColor>
                  </div>
                </el-col>
                <el-col :span="4">
                  <!-- <el-button type="text" size="mini" class="float-right" @click="showCtmBorderCfg = !showCtmBorderCfg">
                    {{!showCtmBorderCfg ? '自定义' : '隐藏'}}
                  </el-button> -->
                </el-col>
              </el-row>
              <div v-if="showCtmBorderCfg" class="mar-top-10">
                <el-row :gutter="10" class="mar-btm-10">
                  <el-col :span="12">
                    <el-input-number
                      v-model="state.backStyle.border.top.width"
                      size="mini" controls-position="right" class="width-input"
                      @change="(val) => stateStylesBulkChange('backStyle.border.top.width', val)"></el-input-number>
                  </el-col>
                  <el-col :span="6">
                    <div class="comBox">
                      <PopoverColor :colorValue="state.backStyle.border.top.color">
                        <CustomColorPicker
                          v-model="state.backStyle.border.top.color" show-alpha
                          @change="(val) => stateStylesBulkChange('backStyle.border.top.color', val)">
                        </CustomColorPicker>
                      </PopoverColor>
                    </div>
                  </el-col>
                  <el-col :span="4">
                    <el-button type="text" size="mini">上</el-button>
                  </el-col>
                </el-row>
                <el-row :gutter="10" class="mar-btm-10">
                  <el-col :span="12">
                    <el-input-number
                      v-model="state.backStyle.border.bottom.width"
                      size="mini" controls-position="right" class="width-input"
                      @change="(val) => stateStylesBulkChange('backStyle.border.bottom.width', val)"></el-input-number>
                  </el-col>
                  <el-col :span="6">
                    <div class="comBox">
                      <PopoverColor :colorValue="state.backStyle.border.bottom.color">
                        <CustomColorPicker
                          v-model="state.backStyle.border.bottom.color" show-alpha
                          @change="(val) => stateStylesBulkChange('backStyle.border.bottom.color', val)">
                        </CustomColorPicker>
                      </PopoverColor>
                    </div>
                  </el-col>
                  <el-col :span="4">
                    <el-button type="text" size="mini">下</el-button>
                  </el-col>
                </el-row>

                <el-row :gutter="10" class="mar-btm-10">
                  <el-col :span="12">
                    <el-input-number
                      v-model="state.backStyle.border.left.width"
                      size="mini" controls-position="right" class="width-input"
                      @change="(val) => stateStylesBulkChange('backStyle.border.left.width', val)"></el-input-number>
                  </el-col>
                  <el-col :span="6">
                    <div class="comBox">
                      <PopoverColor :colorValue="state.backStyle.border.left.color">
                        <CustomColorPicker
                          v-model="state.backStyle.border.left.color" show-alpha
                          @change="(val) => stateStylesBulkChange('backStyle.border.left.color', val)">
                        </CustomColorPicker>
                      </PopoverColor>
                    </div>
                  </el-col>
                  <el-col :span="4">
                    <el-button type="text" size="mini">左</el-button>
                  </el-col>
                </el-row>
                <el-row :gutter="10">
                  <el-col :span="12">
                    <el-input-number
                      v-model="state.backStyle.border.right.width"
                      size="mini" controls-position="right" class="width-input"
                      @change="(val) => stateStylesBulkChange('backStyle.border.right.width', val)"></el-input-number>
                  </el-col>
                  <el-col :span="6">
                    <div class="comBox">
                      <PopoverColor :colorValue="state.backStyle.border.right.color">
                        <CustomColorPicker
                          v-model="state.backStyle.border.right.color" show-alpha
                          @change="(val) => stateStylesBulkChange('backStyle.border.right.color', val)">
                        </CustomColorPicker>
                      </PopoverColor>
                    </div>
                  </el-col>
                  <el-col :span="4">
                    <el-button type="text" size="mini">右</el-button>
                  </el-col>
                </el-row>
              </div>
            </div>
            <!--圆角-->
            <div class="pad-divider">
              <div class="header6 mar-btm">
                <span>圆角</span>
                <el-button type="text" class="font-color-danger mar-lft-10" @click="clearAll('radius')">
                  <i class="iconfont icon-del"></i><span>清空</span>
                </el-button>
              </div>
              <el-row :gutter="10">
                <el-col :span="12">
                  <el-input-number
                    v-model="state.backStyle.borderRadius.width"
                    size="mini" controls-position="right" :min="0" class="width-input"
                    @change="bdrAllChange"></el-input-number>
                </el-col>
                <el-col :span="4">
                  <el-button
                    type="text" size="mini"
                    @click="showCtmBorderRadiusCfg = !showCtmBorderRadiusCfg">
                    {{!showCtmBorderRadiusCfg ? '自定义' : '隐藏'}}
                  </el-button>
                </el-col>
              </el-row>
              <div v-if="showCtmBorderRadiusCfg" class="mar-top-10">
                <el-row :gutter="10">
                  <el-col :span="12" class="mar-btm">
                    <div class="flex-com">
                      <el-button type="text" size="mini" class="mar-rgt-5">上左</el-button>
                      <el-input-number
                        v-model="state.backStyle.borderRadius.topLeft"
                        size="mini" controls-position="right" class="width-input"
                        @change="(val) => stateStylesBulkChange('backStyle.borderRadius.topLeft', val)">
                      </el-input-number>
                    </div>
                  </el-col>
                  <el-col :span="12" class="mar-btm">
                    <div class="flex-com">
                      <el-button type="text" size="mini" class="mar-rgt-5">上右</el-button>
                      <el-input-number
                        v-model="state.backStyle.borderRadius.topRight"
                        size="mini" controls-position="right" class="width-input"
                        @change="(val) => stateStylesBulkChange('backStyle.borderRadius.topRight', val)">
                      </el-input-number>
                    </div>
                  </el-col>
                  <el-col :span="12">
                    <div class="flex-com">
                      <el-button type="text" size="mini" class="mar-rgt-5">下左</el-button>
                      <el-input-number
                        v-model="state.backStyle.borderRadius.bottomLeft"
                        size="mini" controls-position="right" class="width-input"
                        @change="(val) => stateStylesBulkChange('backStyle.borderRadius.bottomLeft', val)">
                      </el-input-number>
                    </div>
                  </el-col>
                  <el-col :span="12">
                    <div class="flex-com">
                      <el-button type="text" size="mini" class="mar-rgt-5">下右</el-button>
                      <el-input-number
                        v-model="state.backStyle.borderRadius.bottomRight"
                        size="mini" controls-position="right" class="width-input"
                        @change="(val) => stateStylesBulkChange('backStyle.borderRadius.bottomRight', val)">
                      </el-input-number>
                    </div>
                  </el-col>
                </el-row>
              </div>
            </div>
            <!--阴影-->
            <div class="pad-divider">
              <div class="header6 mar-btm">
                <span>阴影</span>
                <el-button type="text" class="font-color-danger mar-lft-10" @click="clearAll('shadow')">
                  <i class="iconfont icon-del"></i><span>清空</span>
                </el-button>
              </div>
              <el-row :gutter="10" class="mar-btm-10">
                <el-col :span="8">
                  <div class="comBox">
                    <PopoverColor :colorValue="state.backStyle.shadow.color">
                      <CustomColorPicker
                        v-model="state.backStyle.shadow.color" show-alpha
                        @change="(val) => stateStylesBulkChange('backStyle.shadow.color', val)">
                      </CustomColorPicker>
                    </PopoverColor>
                  </div>
                </el-col>
                <el-col :span="12">
                  <el-select
                    v-model="state.backStyle.shadow.type" placeholder="请选择投影方式"
                    size="mini" class="width-input"
                    @change="(val) => stateStylesBulkChange('backStyle.shadow.type', val)">
                    <el-option v-for="type1 in shadowType" :key="type1.value"
                               :label="type1.label" :value="type1.value"></el-option>
                  </el-select>
                </el-col>
              </el-row>
              <el-row :gutter="10">
                <el-col :span="6">
                  <div class="flex-com-d">
                    <span>X</span>
                    <el-input
                      v-model="state.backStyle.shadow.xOffset"
                      size="mini" controls-position="right" class="width-100 state-input"
                      @change="(val) => stateStylesBulkChange('backStyle.shadow.xOffset', val)"></el-input>
                  </div>
                </el-col>
                <el-col :span="6">
                  <div class="flex-com-d">
                    <span>Y</span>
                    <el-input
                      v-model="state.backStyle.shadow.yOffset"
                      size="mini" controls-position="right" class="width-100 state-input"
                      @change="(val) => stateStylesBulkChange('backStyle.shadow.yOffset', val)"></el-input>
                  </div>
                </el-col>
                <el-col :span="6">
                  <div class="flex-com-d">
                    <span>模糊</span>
                    <el-input
                      v-model="state.backStyle.shadow.blur"
                      size="mini" controls-position="right" class="width-100 state-input"
                      @change="(val) => stateStylesBulkChange('backStyle.shadow.blur', val)"></el-input>
                  </div>
                </el-col>
                <el-col :span="6">
                  <div class="flex-com-d">
                    <span>扩散</span>
                    <el-input
                      v-model="state.backStyle.shadow.spread"
                      size="mini" controls-position="right" class="width-100 state-input"
                      @change="(val) => stateStylesBulkChange('backStyle.shadow.spread', val)"></el-input>
                  </div>
                </el-col>
              </el-row>
            </div>
          </el-form>
        </el-tab-pane>
      </el-tabs>
      <EmptyContent v-else :empty-text="editableMsg" :min-height="400" :image-size="140"></EmptyContent>
    </el-form>
  </div>
</template>

<script>
  import EmptyContent from "@/components/IDE/EmptyContent.vue";
  import ImagePicker from "@/components/IDE/ImagePicker";
  import IconPicker from "@/components/IDE/IconPicker";
  import {WidgetFactory} from '@/modules/IDE/widgetFactory';
  import {dataTypeCfg} from "@/config/ide/common";
  import {mapState} from 'vuex';
  import {getDefaultStyle, WidgetClass} from "@/modules/IDE/widget/atom/widget";
  import {assetBaseUrl} from "@/config/env";
  import iconfont from '@/assets/font/iconfont.json';
  import CustomColorPicker from '@/components/IDE/colorPicker/Color.vue';
  import PopoverColor from '@/components/IDE/colorPicker/Popovers.vue';
  import RectControl from "@/page/IDE/editor/dock/component/RectControl.vue";
  import {copyDomText} from "@/utils";
  import {componentArray} from "@/config/common";

  const objectPath = require("object-path");

  export default {
    name: 'StatesDock',
    components: {
      EmptyContent, ImagePicker, IconPicker, CustomColorPicker, PopoverColor, RectControl
    },
    props: {
      editorType: {
        type: String,
        default: 'room', // room/component
      },
      srcWidget: {
        type: WidgetClass,
        default: () => {
          return {};
        }
      }
    },
    data() {
      return {
        self: undefined,
        widget: {},
        editableMsg: '',
        copyDomText: copyDomText,
        dataTypeCfg: dataTypeCfg,
        fontAlign: [
          {
            label: '左对齐',
            icon: 'icon-leftalignment',
            value: 'left'
          },
          {
            label: '居中',
            icon: 'icon-centeralignment',
            value: 'center'
          },
          {
            label: '右对齐',
            icon: 'icon-rightalignment',
            value: 'right'
          }
        ],
        shadowType: [
          {
            label: '外部投影',
            value: ''
          },
          {
            label: '内部投影',
            value: 'inset'
          }
        ],
        showCtmBorderCfg: false,
        showCtmBorderRadiusCfg: false,
        componentArray: componentArray,
        isEditId: true
      };
    },
    computed: {
      ...mapState({
        selectWidgetIds: state => state.ide.selectWidgetIds,
        activeTheme: state => state.ide.activeTheme,
      }),
      state() {
        return this.srcWidget.getCurrentState();
      },
      backgroundImgSrc() {
        const {backStyle} = this.state;
        const {backgroundImage = ''} = backStyle || getDefaultStyle();
        if (!backgroundImage) return '';
        return `${assetBaseUrl}/file/download/${backgroundImage}`;
      },
      backgroundIconClass() {
        const {font_class = ''} = iconfont.glyphs.find(icon => {
          return icon.unicode === this.state.values.icon;
        }) || {};
        return `icon-${font_class}`;
      },
      backgroundColorObject() {
        const {backStyle} = this.state;
        const {
          backgroundColor = '',
          linearGradient = {direction: 'right', colors: []}
        } = backStyle || getDefaultStyle();
        return {
          backgroundColor: backgroundColor,
          linearGradient: linearGradient
        }
      },
      editable() {
        // 自定义组件的操作中所有组件都能编辑
        if (this.editorType === 'component') return true;
        // 子页面关联组件不可编辑
        if (this.widget.relateSubPage) {
          this.editableMsg = '请前往子页面进行编辑';
          return false;
        }
        // 自定义组件的应用需要判断组件是否开启 isEditing，其子组件只要能被选中，则都能进行编辑
        if (['componentComposite', 'componentDevice'].includes(this.widget.type)) {
          !this.widget.isEditing && (this.editableMsg = '如需编辑，请先开启组件编辑状态');
          return this.widget.isEditing;
        }
        return true;
      },
      sourceText() {
        return this.componentArray.find(item => item.value === this.widget.type).label;
      }
    },
    watch: {
      srcWidget: {
        handler() {
          this.widget = _.cloneDeep(this.srcWidget);
        },
        immediate: true,
      },
    },
    mounted() {
      this.self = this;
      this.$EventBus.$on('undoRedoExecute', () => {
        this.widget = _.cloneDeep(this.srcWidget);
      });
    },
    beforeDestroy() {
      this.$EventBus.$off('undoRedoExecute');
    },
    methods: {
      getDestWidget(widgetId = '') {
        const widget = WidgetFactory.getWidgetById(widgetId);
        const {relateSubPageId} = widget;
        return relateSubPageId ? WidgetFactory.getWidgetById(relateSubPageId) : widget;
      },
      getActiveStateIdx() {
        return this.widget.UI.states.findIndex(state => {
          return state.id === this.widget.UI.state;
        });
      },
      // 组件基础信息批量更改
      widgetBasicBulkChange(key, value) {
        const operation = (widget) => {
          if (!objectPath.has(widget, key)) return;
          objectPath.set(widget, key, value);
          if (key === 'visible') {
            const {ports = {}} = widget;
            const {values = []} = ports;
            const port = values.find(val => val.key === key);
            if (!port) return;
            port.value = value;
          }
        };
        this.operationHandler(operation);
      },
      stateTabClick(tab = {}) {
        if (this.state.id === tab.name) return;
        const activeStateIdx = this.getActiveStateIdx();
        this.selectWidgetIds.forEach(widgetId => {
          const widget = this.getDestWidget(widgetId);
          if (!widget) return;
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          widget.UI.state = state.id;
        });
      },
      stateTabEdit(tabId, action) {
        const activeStateIdx = this.widget.UI.states.findIndex(state => state.id === tabId);
        const confirmMsg = this.selectWidgetIds.length > 1 ? '确定要批量删除组件状态吗' : `确定要删除组件状态吗`;
        switch (action) {
          case 'add':
            this.operationHandler((widget) => {
              widget.addState();
            });
            break;
          case 'remove':
            this.$confirm(confirmMsg, '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.operationHandler((widget) => {
                const {states = []} = widget.UI;
                const state = states[activeStateIdx];
                if (!state) return;
                widget.removeState(state.id);
              });
            }).catch(err => {
            });
            break;
          default:
            break;
        }
      },
      stateBasicBulkChange(key, value) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!objectPath.has(state, key)) return;
          objectPath.set(state, key, value);
        };
        this.operationHandler(operation);
      },
      // 图标按钮文本域值输入特殊处理
      // textarea 在响应 change 事件有问题 Henry 2024-05-23
      stateValueTextInput: _.debounce((self, val) => {
        self.stateValuesBulkChange('values.text', val);

      }, 500),
      // 文本值应用至其他状态
      textApplyToAllStates(text = '') {
        const operation = (widget) => {
          const {states = []} = widget.UI;
          states.forEach(state => state.values.text = text);
        };
        this.operationHandler(operation);
      },
      // 显隐、滑条、进度条、显示器等变量值更改处理，并同步至 ports
      stateValuesBulkChange(key, value, syncToPorts = true) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          if (!objectPath.has(state, key)) return;
          objectPath.set(state, key, value);
          //如果是text和按钮 就同步更改名字
          if(['text','iconTextButton'].includes(widget.category) && key==='values.text'){
            objectPath.set(widget, 'name', `${value}${widget.category==='text'?'的文本':'的图标文本按钮'}`);
          }
          // 将变量同步至 ports
          if (syncToPorts) {
            const {ports = {}} = widget;
            const {values = []} = ports;
            const port = values.find(val => val.key === key.split('.')[1]);
            if (!port) return;
            if (port.key === 'text') {
              port.value = '';
            } else {
              port.value = value;
            }

          }
        };
        this.operationHandler(operation);
      },
      // 批量更改所有选中的组件的样式
      stateStylesBulkChange(key, value) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          if (!objectPath.has(state, key)) return;
          objectPath.set(state, key, value);
          if (key.includes('backStyle.borderRadius')) {
            state.backStyle.borderRadius.width = 0;
          }
        };
        this.operationHandler(operation);
      },
      bdAllWidthChange(val) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          state.backStyle.border.width = val;
          state.backStyle.border.top.width = val;
          state.backStyle.border.left.width = val;
          state.backStyle.border.bottom.width = val;
          state.backStyle.border.right.width = val;
        };
        this.operationHandler(operation);
      },
      bdAllColorChange(val) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          state.backStyle.border.color = val;
          state.backStyle.border.top.color = val;
          state.backStyle.border.left.color = val;
          state.backStyle.border.bottom.color = val;
          state.backStyle.border.right.color = val;
        };
        this.operationHandler(operation);
      },
      bdrAllChange(val) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          state.backStyle.borderRadius = {
            width: val,
            topLeft: val,
            topRight: val,
            bottomLeft: val,
            bottomRight: val
          };
        };
        this.operationHandler(operation);
      },
      clearAll(type) {
        const activeStateIdx = this.getActiveStateIdx();
        const operation = (widget) => {
          const {states = []} = widget.UI;
          const state = states[activeStateIdx];
          if (!state) return;
          if (type === 'border') {
            state.backStyle.border.width = 0
            state.backStyle.border.color = ''
            state.backStyle.border.top.color = '';
            state.backStyle.border.top.width = 0;
            state.backStyle.border.left.color = '';
            state.backStyle.border.left.width = 0;
            state.backStyle.border.bottom.color = '';
            state.backStyle.border.bottom.width = 0;
            state.backStyle.border.right.color = '';
            state.backStyle.border.right.width = 0;
          } else if (type === 'radius') {
            state.backStyle.borderRadius.width = 0
            state.backStyle.borderRadius.topLeft = 0;
            state.backStyle.borderRadius.topRight = 0;
            state.backStyle.borderRadius.bottomLeft = 0;
            state.backStyle.borderRadius.bottomRight = 0;
          } else if (type === 'shadow') {
            state.backStyle.shadow.xOffset = 0
            state.backStyle.shadow.yOffset = 0;
            state.backStyle.shadow.blur = 0;
            state.backStyle.shadow.spread = 0;
            state.backStyle.shadow.color = '';
            state.backStyle.shadow.type = '';
          }
        };
        this.operationHandler(operation);
      },
      operationHandler(operation = () => {
      }) {
        operation(this.widget);
        // 记录组件变更前后的值，用于撤销/重做相关处理
        const widgetChangeArr = [];
        this.selectWidgetIds.forEach(widgetId => {
          const widget = this.getDestWidget(widgetId);
          if (!widget) return;
          const oldWidget = WidgetFactory.getWidgetNecessaryProperty(widget);
          operation(widget);
          const newWidget = WidgetFactory.getWidgetNecessaryProperty(widget);
          widgetChangeArr.push({from: oldWidget, to: newWidget});
        });
        if (!widgetChangeArr.length) return;
        WidgetFactory.undoRedoHdl.operationHdl([{operationType: 'edit', widgets: widgetChangeArr}]);
        this.widget = _.cloneDeep(this.srcWidget);
      },
      jumpToImage(image) {
        this.$EventBus.$emit('jumpToImage', image);
      },
      confirmBgColor(data) {
        this.stateStylesBulkChange('backStyle.backgroundColor', data.backgroundColor)
        this.stateStylesBulkChange('backStyle.linearGradient', data.linearGradient)
      }
    }
  };
</script>

<style scoped lang="less">
  .pad-divider {
    padding: 20px 10px;
    box-sizing: border-box;
    border-bottom: 1px solid #DADCE5;
  }

  .comBox {
    min-width: 60px;
    height: 28px;
    line-height: 28px;
    background: #F7F8FA;
    border-radius: 4px;
    padding-right: 10px;
  }

  .widget-states-dock {
    height: calc(100vh - 90px);
    overflow: auto;
    box-sizing: border-box;

    .el-divider--horizontal {
      width: calc(100% + 30px);
      margin: 5px -15px;
    }

    &::-webkit-scrollbar {
      display: none;
    }
  }

  .flex-com {
    display: flex;
    align-items: center;
  }

  .flex-com-d {
    display: flex;
    flex-direction: column;
    align-items: center;

    span {
      display: inline-block;
      height: 20px;
      font-size: 14px;
    }
  }

  .label-title {
    display: inline-block;
    min-width: 42px;
    color: #12131A;
    font-size: 14px;
    margin-right: 5px;
  }

  .state-input {
    /deep/ .el-input__inner {
      background: #F7F8FA;
      border: none;
      outline: none;
    }
  }

  .width-input {
    width: 100%;

    /deep/ .el-input__inner {
      background: #F7F8FA;
    }
  }

  .flex-com-box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
  }

  .flex-item {
    width: calc(50% - 10px);

    .title {
      width: 10px;
      margin-right: 15px;
      font-size: 14px;
    }
  }


  .color-border {
    width: 28px;
    height: 28px;
    padding: 4px;
    border: 1px solid #e6e6e6;
    border-radius: 4px;
    background: transparent;

    .color-border-box {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px solid #999;
      background-image: url();

      .arrow {
        color: #fff;
        font-size: 16px;
      }
    }
  }
</style>
